package com.volunteer.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.volunteer.common.BusinessException;
import com.volunteer.common.ResultCode;
import com.volunteer.entity.Activity;
import com.volunteer.entity.UserCollection;
import com.volunteer.entity.User;
import com.volunteer.mapper.ActivityMapper;
import com.volunteer.mapper.CollectionMapper;
import com.volunteer.mapper.UserMapper;
import com.volunteer.service.CollectionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 收藏服务实现类
 */
@Service
@RequiredArgsConstructor
public class CollectionServiceImpl extends ServiceImpl<CollectionMapper, UserCollection> implements CollectionService {

    private final ActivityMapper activityMapper;
    private final UserMapper userMapper;

    /**
     * 添加收藏
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 是否成功
     */
    @Override
    public boolean addCollection(Long activityId, Long userId) {
        if (activityId == null || userId == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查活动是否存在
        Activity activity = activityMapper.selectById(activityId);
        if (activity == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        // 检查是否已收藏
        if (isUserCollected(activityId, userId)) {
            throw new BusinessException("您已收藏该活动");
        }

        // 检查活动状态
        if (activity.getStatus() == 4) {
            throw new BusinessException("活动已取消，无法收藏");
        }

        // 创建收藏记录
        UserCollection userCollection = new UserCollection();
        userCollection.setActivityId(activityId);
        userCollection.setUserId(userId);
        userCollection.setCreateTime(LocalDateTime.now());

        return this.save(userCollection);
    }

    /**
     * 取消收藏
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 是否成功
     */
    @Override
    public boolean cancelCollection(Long activityId, Long userId) {
        if (activityId == null || userId == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        // 检查是否已收藏
        LambdaQueryWrapper<UserCollection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCollection::getActivityId, activityId)
                .eq(UserCollection::getUserId, userId);

        return this.remove(queryWrapper);
    }

    /**
     * 查询用户是否已收藏活动
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 是否已收藏
     */
    @Override
    public boolean isUserCollected(Long activityId, Long userId) {
        if (activityId == null || userId == null) {
            return false;
        }

        LambdaQueryWrapper<UserCollection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCollection::getActivityId, activityId)
                .eq(UserCollection::getUserId, userId);

        return this.count(queryWrapper) > 0;
    }

    /**
     * 查询用户收藏的活动数量
     *
     * @param userId 用户ID
     * @return 收藏数量
     */
    @Override
    public int countUserCollections(Long userId) {
        if (userId == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        LambdaQueryWrapper<UserCollection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCollection::getUserId, userId);

        return Math.toIntExact(this.count(queryWrapper));
    }

    /**
     * 查询活动的收藏数量
     *
     * @param activityId 活动ID
     * @return 收藏数量
     */
    @Override
    public int countActivityCollections(Long activityId) {
        if (activityId == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }

        LambdaQueryWrapper<UserCollection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCollection::getActivityId, activityId);

        return Math.toIntExact(this.count(queryWrapper));
    }

    @Override
    public boolean toggleCollection(Long activityId, Integer type) {
        if (type == 1) {
            return addCollection(activityId, StpUtil.getLoginIdAsLong());
        } else if (type == 0) {
            return cancelCollection(activityId, StpUtil.getLoginIdAsLong());
        }
        return false;
    }
}
